package com.jml.核心注解002;


import com.jml.核心注解002.config.FactoryBeanConfig005;
import com.jml.核心注解002.config.ImportBeanDefinitionRegistrarConfig004;
import com.jml.核心注解002.config.ImportConfig002;
import com.jml.核心注解002.config.ImportEnableConfig003;
import com.jml.核心注解002.config.MyFactoryBean;
import com.jml.核心注解002.entity.MyEntity;
import com.jml.核心注解002.entity.Win7Entity;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author:jml
 * @date: 2019/9/23 9:46
 * @description：
 */
public class MainSpring01 {

    public static void main(String[] args) throws Exception {
        //@Conditional注解
       /* AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        Win7Entity bean = applicationContext.getBean(Win7Entity.class);
        MyEntity myEntity1 = (MyEntity)applicationContext.getBean("myFactoryBean");
        MyEntity myEntity2 = (MyEntity)applicationContext.getBean("myFactoryBean");
        System.out.println(myEntity1==myEntity2);*/
        
        
        //@Import注解
        /*AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
                ImportConfig002.class);
        Win7Entity bean = (Win7Entity)applicationContext.getBean("com.jml.核心注解002.entity.Win7Entity");*/
        /*
        @Import()注解和Bean注解的区别：
            1.bean注解的id是方法名称，import注解是全限定类名
            2.import相对来说简单
            3.共同的应用场景，都是引入外部jar包
        */
    
        //@enablexxx,Import
        /*AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
                ImportEnableConfig003.class);*/
        
        
        //ImportBeanDefinitionRegistrar,手动注入对象
        /*AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
                ImportBeanDefinitionRegistrarConfig004.class);*/
        
        
        //FactoryBean注入对象
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
                FactoryBeanConfig005.class);
        MyEntity myFactoryBean = (MyEntity)applicationContext.getBean("myFactoryBean");
        System.out.println(myFactoryBean);
    
    
        //得到所有的bean的id名字
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (int i = 0; i < beanDefinitionNames.length; i++) {
            System.out.println(beanDefinitionNames[i]);
        }

//        System.out.println(bean);
    }


    //注册的源码
    /*<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, BeanDe finitionCustomizer... definitionCustomizers) {

        //注解方式的BeanDefinition
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
        //判断是否有使用Conditional条件方式注入Bean
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
        //设置回调
        abd.setInstanceSupplier(instanceSupplier);
        //判断config类上是否有scope作用域
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        //设置scope
        abd.setScope(scopeMetadata.getScopeName());
        //判断是否有传递beanName，如果没有就生成beanname，默认是类名小写作为类id
        //如果是注解启动bean，获取方法的名字，如果都没有设置，为空和null就用首字母小写类名
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
            for (Class<? extends Annotation> qualifier : qualifiers) {
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }
        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
            customizer.customize(abd);
        }

        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }*/
}
